package com.netdisk.service.impl;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.netdisk.dto.FileDTO;
import com.netdisk.entity.File;
import com.netdisk.entity.Trash;
import com.netdisk.exception.BusinessException;
import com.netdisk.mapper.TrashMapper;
import com.netdisk.service.FileService;
import com.netdisk.service.TrashService;
import com.netdisk.service.UserService;
import com.netdisk.vo.PageResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 回收站服务实现类
 */
@Service
public class TrashServiceImpl extends ServiceImpl<TrashMapper, Trash> implements TrashService {

    @Value("${file.upload-dir}")
    private String uploadDir;

    @Autowired
    private FileService fileService;

    @Autowired
    private UserService userService;

    @Override
    public PageResult<FileDTO> listTrashFiles(Integer userId, Integer page, Integer pageSize, String query) {
        // 计算分页参数
        int offset = (page - 1) * pageSize;
        
        // 查询结果
        List<File> files;
        int total;
        
        if (query != null && !query.isEmpty()) {
            // 带搜索条件的查询
            files = baseMapper.selectTrashFilesWithQueryDirectSQL(userId, pageSize, offset, query);
            total = baseMapper.countTrashFilesWithQuery(userId, query);
        } else {
            // 无搜索条件的查询
            files = baseMapper.selectTrashFilesDirectSQL(userId, pageSize, offset);
            total = baseMapper.countTrashFiles(userId);
        }

        // 转换为DTO
        List<FileDTO> fileDTOList = files.stream().map(file -> {
            FileDTO fileDTO = new FileDTO();
            BeanUtils.copyProperties(file, fileDTO);
            return fileDTO;
        }).collect(Collectors.toList());

        // 返回分页结果
        return new PageResult<>((long) total, fileDTOList);
    }

    @Override
    public FileDTO getTrashFileInfo(Integer fileId, Integer userId) {
        try {
            // 检查文件是否在回收站
            LambdaQueryWrapper<Trash> trashQueryWrapper = new LambdaQueryWrapper<>();
            trashQueryWrapper.eq(Trash::getFileId, fileId)
                    .eq(Trash::getUserId, userId);
            
            if (this.count(trashQueryWrapper) == 0) {
                throw new BusinessException("文件不在回收站中");
            }
            
            // 获取文件信息
            File file = fileService.getById(fileId);
            if (file == null) {
                throw new BusinessException("文件不存在");
            }
            
            // 转换为DTO
            FileDTO fileDTO = new FileDTO();
            BeanUtils.copyProperties(file, fileDTO);
            
            return fileDTO;
        } catch (Exception e) {
            throw new BusinessException("获取回收站文件信息失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean restoreFile(Integer fileId, Integer userId) {
        // 检查文件是否在回收站
        LambdaQueryWrapper<Trash> trashQueryWrapper = new LambdaQueryWrapper<>();
        trashQueryWrapper.eq(Trash::getFileId, fileId)
                .eq(Trash::getUserId, userId);
        if (this.count(trashQueryWrapper) == 0) {
            throw new BusinessException("文件不在回收站中");
        }

        // 恢复文件
        LambdaUpdateWrapper<File> fileUpdateWrapper = new LambdaUpdateWrapper<>();
        fileUpdateWrapper.eq(File::getId, fileId)
                .set(File::getDeletedAt, null);
        boolean result = fileService.update(fileUpdateWrapper);

        // 从回收站中删除
        if (result) {
            this.remove(trashQueryWrapper);
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteFileCompletely(Integer fileId, Integer userId) {
        // 检查文件是否在回收站
        LambdaQueryWrapper<Trash> trashQueryWrapper = new LambdaQueryWrapper<>();
        trashQueryWrapper.eq(Trash::getFileId, fileId)
                .eq(Trash::getUserId, userId);
        if (this.count(trashQueryWrapper) == 0) {
            throw new BusinessException("文件不在回收站中");
        }

        // 获取文件信息
        File file = fileService.getById(fileId);
        if (file == null) {
            throw new BusinessException("文件不存在");
        }

        // 删除物理文件
        String filePath = uploadDir + "/" + file.getPath();
        if (FileUtil.exist(filePath)) {
            FileUtil.del(filePath);
        }

        // 更新用户已使用存储空间
        userService.updateStorageUsed(userId, -file.getSize());

        // 删除数据库记录
        boolean result = fileService.removeById(fileId);
        if (result) {
            this.remove(trashQueryWrapper);
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean clearTrash(Integer userId) {
        // 查询用户回收站中的所有文件
        LambdaQueryWrapper<Trash> trashQueryWrapper = new LambdaQueryWrapper<>();
        trashQueryWrapper.eq(Trash::getUserId, userId);
        List<Trash> trashList = this.list(trashQueryWrapper);

        // 如果回收站为空，直接返回成功
        if (trashList.isEmpty()) {
            return true;
        }

        // 批量删除文件
        long totalSize = 0;
        for (Trash trash : trashList) {
            File file = fileService.getById(trash.getFileId());
            if (file != null) {
                // 删除物理文件
                String filePath = uploadDir + "/" + file.getPath();
                if (FileUtil.exist(filePath)) {
                    FileUtil.del(filePath);
                }
                totalSize += file.getSize();
                fileService.removeById(file.getId());
            }
        }

        // 更新用户已使用存储空间
        if (totalSize > 0) {
            userService.updateStorageUsed(userId, -totalSize);
        }

        // 清空回收站
        return this.remove(trashQueryWrapper);
    }
} 